#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include "lab01.h"
#include "envel.h"
#define MAX 10
#define false 0
#define true 1
#define SEPARADOR '#'

int arqvalido(FILE *f, char *argv[], int aux) //conta se tem tres #'s no arq de entrada
{
	FILE *l;
    int contaseparador = 0, i, flag = false;
    char controle, c;

    if (!arqExistente(f)) //verifica se o arquivo existe
    {
    	l = fopen(argv[aux], "r");
    	for(i=0;i<1;i++){
    		do
    			c=getc(l);
    		while(c != '\n');
    	}
    	do
    		putchar(c = getc(l));
    	while(c!= '\n');
    	fclose(l);

    return false;
    }

    controle = getc(f);

    while (controle != EOF) //verifica se existem #'s seguidos, o que � errado
    {
          if (controle != SEPARADOR) flag = true; //flag eh pra ver se tem pelo menos um caractere nao # entre dois #'s
          else
          {
              contaseparador++;
              if (flag == false)
              {
            	  l = fopen(argv[aux], "r");/*percorre os arquivo de configuração procurando a mensagen a ser exibida*/
            	  for(i=0;i<2;i++){
                		do
            	      		c=getc(l);
            	      	while(c != '\n');
            	  }
            	  do
            		  putchar(c = getc(l));
            	  while(c!= '\n');
            	  fclose(l);

            	  return false;
              }
              else flag = false;
          }
          controle = getc(f);
    }

    if (contaseparador == 3) return true;
    else
    {
    	l = fopen(argv[aux], "r");/*percorre os arquivo de configuração procurando a mensagen a ser exibida*/
			for(i=0;i<2;i++){
				do
					c=getc(l);
				while(c != '\n');
    	    }
    	    do
    	    	putchar(c = getc(l));
    	    while(c!= '\n');
    	    fclose(l);

    	return false;
    }
}

/*funcao que separa o nome completo em um vetor de apontadores para cada parte do nome*/
int vetorNomes(FILE *f, char **nome)
{
	char *aux, string[100], chr;
	int i=0;

	chr = getc(f);

	while(chr != SEPARADOR)
	{
        string[i] = chr;
        i++;
        chr = getc(f);
    }
    string[i] = '\0';
    i = 0;

	aux = strtok(&string[0], " ");

    /*coloca cada parte do nome em uma posicao do vetor de apontadores*/
	while(aux != NULL){
        /*alocacao de memoria dinamica*/
		nome[i] = (char*)Malloc(sizeof(aux));
		strcpy((nome[i]), aux);
		aux = strtok(NULL, " "); /* Separador*/
		i++;
	}

	return i;
}

int montarRA(char *ra, FILE *f, char *argv[], int aux)
{
	FILE *l;
    int i = 0;
    char chr, c;

    /*proximas tres linhas sao para pular o nome*/
    chr = getc(f);
    while (chr != SEPARADOR) chr = getc(f);
    chr = getc(f);

    while (chr != SEPARADOR) //guarda RA no vetor
    {
          ra[i] = chr;
          i++;
          chr = getc(f);
    }
    ra[i] = '\0';

    if (!confereRA(ra)) //verifica se RA possui somente numeros
    {
    	l = fopen(argv[aux], "r");/*percorre os arquivo de configuração procurando a mensagen a ser exibida*/
    	    for(i=0;i<3;i++){
    	    	do
    	    		c=getc(l);
    	   		while(c != '\n');
    	   	}
    	   	do
    	   		putchar(c = getc(l));
        	while(c!= '\n');
   	    	fclose(l);

        return false;
    }
    return true;
}

/*funcao que confere se o RA foi fornecido corretamente*/
int confereRA(char *ra)
{
    while (*ra != '\0')
    {
          /*verifica se o RA realmente contem apenas numeros*/
          if (*ra < '0' || *ra > '9') return false;
          else ra++;
    }
    return true;
}

char achaChr(FILE *f)
{
    int i = 0;
    char chr;

    chr = getc(f);
    while (i != 2)
    {
          while (chr != SEPARADOR) chr = getc(f);
          chr = getc(f);
          i++;
    }
    return chr;
}

void controleCardapio(FILE *f, char *nome[], char *ra, int numeroNomes, char *argv[], int aux, char chr)
{
	FILE *l;
	int controle = 0, i;
	char c;

	/*loop que verifica a opcao desejada pelo usuario*/
	    while (controle != 6)
		{

			/*mostra ao usuario o cardapio de opcoes*/
	        printf("______________________________________________________________________________________");
			printf("\n______________________________________________________________________________________");
			printf("\n\n");
			l = fopen(argv[aux], "r");
				for(i=0;i<4;i++){
					do
						c=getc(l);
			    	while(c != '\n');
				}
				do
			    	putchar(c = getc(l));
			    while(c!= '\n');
			printf("\n");
			while(i<11){
				do
					putchar(c=getc(l));
				while(c != '\n');
				i++;
			}
			fclose(l);

			/*espera o usuario digitar a opcao desejada*/
	        scanf("%d", &controle);

			/*limpar buffer de entrada*/
	        getchar();


				switch(controle){
	                /*executa a opcao 1*/
					case 1:
						apresentaDados(nome, ra, numeroNomes, argv, aux);
						break;
					/*executa a opcao 2*/
	                case 2:
						converteMaiuscula(nome, numeroNomes, argv, aux);
						break;
					/*executa a opcao 3*/
	                case 3:
						apresentaPartes(nome, numeroNomes, argv, aux);
						break;
					/*executa a opcao 4*/
	                case 4:
						buscaCaracter(nome, numeroNomes, chr, argv, aux);
						break;
					/*executa a opcao 5*/
	                case 5:
	                    separaPartes(f, argv, aux);
	                    fclose(f); f = fopen(argv[1], "r");
	                    break;
	                /*executa a opcao 6*/
	                case 6:
						break;
					/*exibe mensagem de erro se a opcao nao existir*/
	                default:
						printf("===>");
						l = fopen(argv[aux], "r");/*percorre os arquivo de configuração procurando a mensagen a ser exibida*/
							for(i=0;i<12;i++){
								do
									c=getc(l);
								while(c != '\n');
						    }
						    do
						    	putchar(c = getc(l));
						    while(c!= '\n');
						    fclose(l);
						break;
				}
		}
}

/*funcao que apresente os dados do aluno na tela*/
void apresentaDados(char *nome[], char *ra, int numeroNomes, char *argv[], int aux)
{
	FILE *l;
	int i;
	char c;

	printf("---------------------------------------");

	printf("\n\n");
	l = fopen(argv[aux], "r");/*percorre os arquivo de configuração procurando a mensagen a ser exibida*/
		for(i=0;i<14;i++){
			do
				c=getc(l);
			while(c != '\n');
		}
		do
			putchar(c = getc(l));
		while(c!= '\n');
		fclose(l);

    /*imprime na tela o RA seguido do nome do aluno*/
	printf("\n%s - ", ra);
	for(i=0; i<numeroNomes; i++){
		printf("%s ", nome[i]);
	}

	printf("\n\n\n");
	l = fopen(argv[aux], "r");/*percorre os arquivo de configuração procurando a mensagen a ser exibida*/
		for(i=0;i<13;i++){
			do
				c=getc(l);
			while(c != '\n');
		}
		do
			putchar(c = getc(l));
		while(c!= '\n');
		fclose(l);

    /*espera o usuario digitar enter*/
	getchar();

	printf("\n\n\n");

return;
}

/*funcao que converte o nome do aluno para letras maiusculas*/
void converteMaiuscula(char *nomes[], int numeroNomes, char *argv[], int aux)
{
	FILE *l;
	int nome, letra, i;
	char c;

	printf("---------------------------------------");

	printf("\n\n");
	l = fopen(argv[aux], "r");/*percorre os arquivo de configuração procurando a mensagen a ser exibida*/
		for(i=0;i<15;i++){
			do
				c=getc(l);
			while(c != '\n');
		}
		do
			putchar(c = getc(l));
		while(c!= '\n');
		fclose(l);

    /*percorre cada parte do nome completo do aluno*/
	for(nome=0; nome<numeroNomes; nome++){
		letra=0;
		/*percorre cada caracter do nome, convertendo-o para maiusculo*/
		while(nomes[nome][letra] != '\0'){
				printf("%c", toupper(nomes[nome][letra]));
				letra++;
		}
		printf(" ");
	}

	printf("\n\n\n");
	l = fopen(argv[aux], "r");
		for(i=0;i<13;i++){
			do
				c=getc(l);
			while(c != '\n');
		}
		do
			putchar(c = getc(l));
		while(c!= '\n');
		fclose(l);

	    /*espera o usuario digitar enter*/
		getchar();

		printf("\n\n\n");

return;
}

/*funcao que apresenta as partes que compoem o nome*/
void apresentaPartes(char *nome[], int i, char *argv[], int aux2) {

	FILE *l;
	int ind, aux, max, flag, i2;

	char *in, c;

	printf("---------------------------------------");

	printf("\n\n");
	l = fopen(argv[aux2], "r"); /*percorre os arquivo de configuração procurando a mensagen a ser exibida*/
		for(i2=0;i2<16;i2++){
			do
				c=getc(l);
			while(c != '\n');
		}
		do
			putchar(c = getc(l));
		while(c!= '\n');
		fclose(l);

	/*percorre cada parte do nome completo do aluno*/
    for (aux = 0; aux < i; aux++){

			ind=0;
			flag=false;

			in = nome[aux];

			max=strlen(in);

            /*percorre cada caracter do nome*/
			while (ind != max){
                /*imprime o caracter caso ele seja valido*/
				if ((in[ind] >= '0' && in[ind] <= '9') || (in[ind] >='a' && in[ind] <= 'z') || (in[ind] >='A' && in[ind] <= 'Z'))
				{
					flag=true;
					printf ("%c", in[ind]);
					ind++;
				}
				/*elimina o caracter caso ele seja invalido*/
				else
				{
					ind=eliminaCaracterInvalido(in, ind);

				}
			}
			/*muda de linha caso o nome estiver terminado*/
			if ((flag) && (aux != i-1)){
				flag=false;
				printf("\n");
			}

	}


	printf("\n\n\n");
	l = fopen(argv[aux2], "r"); /*percorre os arquivo de configuração procurando a mensagen a ser exibida*/
		for(i2=0;i2<13;i2++){
			do
				c=getc(l);
			while(c != '\n');
		}
		do
			putchar(c = getc(l));
		while(c!= '\n');
		fclose(l);

		/*espera o usuario digitar enter*/
		getchar();

		printf("\n\n\n");

return;
}

/*funcao que elimina o caracter se ele for invalido*/
int eliminaCaracterInvalido(char *in, int ind){

	ind++;//contador

	/*confere se o caracter e mesmo invalido*/
    if ((in[ind]>= '0' || in[ind] <= '9') || (in[ind] >='a' && in[ind] <= 'z') || (in[ind] >='A' && in[ind] <= 'Z'))
	{
		return(ind);
	}
	/*elimina o caracter se ele realmente for invalido*/
    else
	{
		ind++;
		ind=eliminaCaracterInvalido(in, ind);
		return(ind);
	}
}

/*funcao que busca um determinado caracter no nome do aluno*/
void buscaCaracter(char *nome[], int i, char chr, char *argv[], int aux2)
{
	FILE *l;
	char *ap, c;
	int contador = 0, aux = 0, i2;

	printf("---------------------------------------");

	printf("\n\n");
	l = fopen(argv[aux2], "r");
		for(i2=0;i2<17;i2++){ //percorre o arquivo de configuração procurando a mensagen a ser exibida
			do
				c=getc(l);
			while(c != '\n');
		}
		do
			putchar(c = getc(l));
		while(c!= ':');
		fclose(l);

	printf("'%c' \n\n", chr);

    /*percorre cada parte do nome completo do aluno*/
	for (aux = 0; aux < i; aux++){

		ap = nome[aux];

		/*percorre o nome, buscando o caracter procurado*/
        while (ap != NULL)
		{
				ap = memchr(ap, chr, strlen(ap));
				/*atualiza o contador quando o caracter � encontrado*/
				if (ap != NULL)
				{
					contador++;
					ap++;
				}
		}
	}

	/*imprime na tela quantas vezes o caracter procurado foi encontrado*/
	l = fopen(argv[aux2], "r");

		for(i2=0;i2<18;i2++){
			do
				c=getc(l);
			while(c != '\n');
		}
		do
			putchar(c = getc(l));
		while(c!= ':');

		printf(" %d", contador);

		do
			putchar(c = getc(l));
		while(c!= '\n');
		fclose(l);

	printf("\n\n\n");
	l = fopen(argv[aux2], "r");
		for(i2=0;i2<13;i2++){
			do
				c=getc(l);
			while(c != '\n');
		}
		do
			putchar(c = getc(l));
		while(c!= '\n');
		fclose(l);

	/*espera o usuario digitar enter*/
    getchar();

	printf("\n\n\n");

	return;
}

void separaPartes(FILE *f, char *argv[], int aux)
{
	FILE *l;
    char chr, string[MAX*10], stop[MAX], *ap = NULL, *ap2, c;
    int i = 0, i2;

    chr = fgetc(f);
    while(chr != SEPARADOR) //copia o nome do arq de entrada para string
	{
        string[i] = chr;
        i++;
        chr = getc(f);
    }
    string[i] = '\0'; //String de termino

    l = fopen(argv[aux], "r");
		for(i2=0;i2<19;i2++){
			do
				c=getc(l);
        	while(c != '\n');
        }
        do
        	putchar(c = getc(l));
        while(c!= ':');
       	fclose(l);

    gets(stop); //coleta separadores fornecidos pelo usuario
    printf("\n");
    ap2 = &stop[0];
    i = 0;
    stop[strlen(stop)+1] = '\0';
    stop[strlen(stop)] = SEPARADOR;

    while (chr != '\0')
    {
          ap = NULL;

          do
          {
                ap = memchr(ap2, chr, strlen(ap2)); //Realiza a quebra
                if (ap != NULL)
                {
                       chr = string[i]; //vetor preenchido com as quebras da string de entrada
                       i++;
                }
          }while (ap != NULL);


          while (ap == NULL && i <= strlen(string))
          {
                putchar(chr);
                chr = string[i];
                i++;
                ap = memchr(ap2, chr, strlen(ap2));
          }
          printf("\n");
          chr = string[i];
          i++;
    }
    printf("\n");

}


/*funcao principal do programa*/
int main (int argc, char *argv[])
{
    /*declaracao das variaveis e do vetor de apontadores*/
	int i, aux;
    char *nome [MAX], ra[MAX], chr, c;
    FILE *f, *l;

    /*mostra ao usuario as opcoes de idioma disponiveis*/
    printf("______________________________________________________________________________________");
    printf("\n______________________________________________________________________________________");
    printf("\nPor favor, selecione o idioma desejado\nPlease select one language to proceed\nPor favor, seleccione un idioma para continuar\n");
    printf("\n\nPortugues (p)\nEnglish (i)\nEspanol (e)\n");

    scanf("%c", &c);

    if(c == 'p'){
        aux = 1;
    } else if(c == 'i'){
        aux = 2;
    } else {
        aux = 3;
    }

    /*verifica se o numero de argumentos esta correto*/
	if (argc < 5){

		l = fopen(argv[aux], "r");
		do
			putchar(c = getc(l));
		while(c!= '\n');
		fclose(l);

    return 0;
    }

    f = fopen(argv[4], "r");

    if (!arqvalido(f, argv, aux)) return 0;
    fclose(f); f = fopen(argv[4], "r");

    i = vetorNomes(f, &nome[0]);
    fclose(f); f = fopen(argv[4], "r");

    if (!montarRA(&ra[0], f, argv, aux)) return 0;
    fclose(f); f = fopen(argv[4], "r");

    chr = achaChr(f);
    fclose(f); f = fopen(argv[4], "r");

    controleCardapio(f, nome, ra, i, argv, aux, chr);

return 0;
}
